package menu

import (
	"github.com/ouqiang/gocron/internal/models"
	"path/filepath"
	"strings"
)

type RouterVo struct {
	Hidden     bool       `json:"hidden"`
	Name       string     `json:"name"`
	Path       string     `json:"path"`
	Component  string     `json:"component"`
	Query      string     `json:"query"`
	Meta       MetaVo     `json:"meta"`
	AlwaysShow bool       `json:"alwaysShow"`
	Redirect   string     `json:"redirect"`
	Children   []RouterVo `json:"children"`
}

type MetaVo struct {
	Title   string `json:"title"`
	Icon    string `json:"icon"`
	IsCache bool   `json:"isCache"`
	Path    string `json:"path"`
}

var (
	dir_type    = "M"
	menu_type   = "C"
	button_type = "F"
	no_frame    = 1
	layout      = "Layout"
	parent_view = "ParentView"
	inner_link  = "InnerLink"
)

func BuildRouter(list []models.SysMenu) []RouterVo {
	//var routers []RouterVo
	return buildMenuTree(list, 0)
}

func getRouteName(menu models.SysMenu) string {
	name := strings.Title(menu.Path)
	if isMenuFrame(menu) {
		return ""
	}
	return name
}

func getRouterPath(menu models.SysMenu) string {
	path := menu.Path
	if menu.ParentId != 0 && isInnerLink(menu) {
		replacer := strings.NewReplacer("https://", "", "http://", "", "www.", "", ".", "/", ":", "/")
		path = replacer.Replace(path)
	}
	if menu.ParentId == 0 && dir_type == menu.MenuType && no_frame == menu.IsFrame {
		path = filepath.Join("/", path)
	} else if isMenuFrame(menu) {
		path = "/"
	}
	return path
}

func getComponent(menu models.SysMenu) string {
	component := layout
	if len(strings.TrimSpace(menu.Component)) > 0 && !isMenuFrame(menu) {
		component = menu.Component
	} else if len(strings.TrimSpace(menu.Component)) == 0 && menu.ParentId != 0 && isInnerLink(menu) {
		component = inner_link
	} else if len(strings.TrimSpace(menu.Component)) == 0 && isParentView(menu) {
		component = parent_view
	}
	return component
}

func buildMenuTree(menus []models.SysMenu, parentId int64) []RouterVo {
	var menuTree []RouterVo
	for _, menu := range menus {
		if menu.ParentId == parentId {
			node := RouterVo{
				Hidden:    menu.Visible == "1",
				Name:      getRouteName(menu),
				Path:      getRouterPath(menu),
				Component: getComponent(menu),
				Query:     menu.Query,
				Meta: MetaVo{
					Title:   menu.MenuName,
					Icon:    menu.Icon,
					IsCache: menu.IsCache == 1,
					Path:    menu.Path,
				},
				Children: buildMenuTree(menus, menu.MenuId),
			}
			if len(node.Children) > 0 && dir_type == menu.MenuType {
				node.AlwaysShow = true
				node.Redirect = "noRedirect"
			} else if isMenuFrame(menu) {
				node.Meta = MetaVo{}
				child := RouterVo{
					Name:      getRouteName(menu),
					Path:      getRouterPath(menu),
					Component: getComponent(menu),
					Meta: MetaVo{
						Title:   menu.MenuName,
						Icon:    menu.Icon,
						IsCache: menu.IsCache == 1,
						Path:    menu.Path,
					},
					Query: menu.Query,
				}
				menuTree = append(node.Children, child)
			} else if menu.ParentId == 0 && isInnerLink(menu) {
				node.Meta = MetaVo{
					Title: menu.MenuName,
					Icon:  menu.Icon,
				}
				node.Path = "/"
				child := RouterVo{
					Name:      getRouteName(menu),
					Path:      getRouterPath(menu),
					Component: getComponent(menu),
					Meta: MetaVo{
						Title:   menu.MenuName,
						Icon:    menu.Icon,
						IsCache: menu.IsCache == 1,
						Path:    menu.Path,
					},
				}
				menuTree = append(node.Children, child)
			}
			menuTree = append(menuTree, node)
		}
	}
	return menuTree
}

func isMenuFrame(menu models.SysMenu) bool {
	return menu.ParentId == 0 && menu_type == menu.MenuType && no_frame == menu.IsFrame
}

func isInnerLink(menu models.SysMenu) bool {
	return no_frame == menu.IsFrame && (strings.HasPrefix(strings.ToLower(menu.Path), "http://") || strings.HasPrefix(strings.ToLower(menu.Path), "https://"))
}
func isParentView(menu models.SysMenu) bool {
	return menu.ParentId != 0 && dir_type == menu.MenuType
}
